package com.example.demo.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 郝文雪
 * @date 2022/8/2 11:35
 * @Description Test
 */
@Aspect //表示当前类是一个切面
@Component
@Slf4j
public class UserAspect {
    //定义切点（定义规则：拦截UserController下的所有方法）
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointCut(){}

    //定义前置通知（AOP拦截之后具体的业务执行）
    @Before("pointCut()")
    public void doBefore(){
        log.info("执行了前置通知方法");
    }
    //后置通知方法
    @After("pointCut()")
    public void doAfter(){
        log.info("执行了后置通知");
    }

    //异常抛出之后的通知
    @AfterThrowing("pointCut()")
    public void doAfterThrowing(){
        log.info("异常之后的通知");
    }

    //返回值异常
    @AfterReturning("pointCut()")
    public void doAfterRunning(){
        log.info("执行return通知");
    }

    //环绕通知
    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint){
        Object result=null;
        //1.环绕通知的前置方法
        long stime = System.currentTimeMillis();
        log.info("自定义环绕通知的前置方法");
        try {
            result=joinPoint.proceed(); //执行了拦截的方法
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long etime = System.currentTimeMillis();
        log.info("自定义环绕通知的后置方法");
        log.info("方法执行花费了："+(etime-stime));
        return result;
    }
}
